package com.cjm.one.system.service.impl;

import cn.hutool.core.util.ReUtil;
import cn.hutool.jwt.JWT;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import com.cjm.one.common.constant.REConstants;
import com.cjm.one.common.constant.RedisConstants;
import com.cjm.one.common.constant.TokenConstants;
import com.cjm.one.common.enums.UserEnums;
import com.cjm.one.common.exception.GlobalException;
import com.cjm.one.common.result.ResultCodeEnum;
import com.cjm.one.common.utils.JSONUtils;
import com.cjm.one.model.system.entity.SysResource;
import com.cjm.one.model.system.entity.SysRole;
import com.cjm.one.model.system.entity.SysUserRole;
import com.cjm.one.model.system.vo.RoleResVo;
import com.cjm.one.model.system.vo.SysResourceVo;
import com.cjm.one.system.mapper.SysResourceMapper;
import com.cjm.one.system.mapper.SysRoleMapper;
import com.cjm.one.system.mapper.SysUserInfoMapper;
import com.cjm.one.system.mapper.SysUserRoleMapper;
import com.cjm.one.system.service.AuthSystemService;

import com.cjm.one.model.auth.system.dto.LoginDto;
import com.cjm.one.model.system.entity.SysUserInfo;
import com.cjm.one.system.service.SysRoleService;
import com.fasterxml.jackson.core.JsonProcessingException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AuthSystemServiceImpl implements AuthSystemService {
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private SysUserInfoMapper sysUserInfoMapper;
    @Resource
    private SysUserRoleMapper  sysUserRoleMapper;
    @Resource
    private SysResourceMapper sysResourceMapper;
    @Resource
    private SysRoleMapper sysRoleMapper;

    @Override
    public String login(LoginDto loginDto) {
        log.info("系统用户登录：loginDto:{}", loginDto);
        String code = (String) redisTemplate.opsForValue().get(RedisConstants.CAPTCHA_IMG_KEY +loginDto.getCodeKey());
        log.info("系统用户验证码：code:{},istrue:{}", code,StringUtils.hasText(code));
        if (!StringUtils.hasText(code)){
            throw new GlobalException(ResultCodeEnum.CAPTCHA_TIMEOUT_ERROR);
        }
        boolean isEquation = code.equalsIgnoreCase(loginDto.getCode());
        if (!isEquation) {
            throw new GlobalException(ResultCodeEnum.CAPTCHA_CODE_ERROR);
        }
        // 登录逻辑
        if (!StringUtils.hasText(loginDto.getUsername())) {
            throw new GlobalException(ResultCodeEnum.USERNAME_EMPTY);
        }
        if (!StringUtils.hasText(loginDto.getPassword())) {
            throw new GlobalException(ResultCodeEnum.PASSWORD_EMPTY);
        }
        if (ReUtil.isMatch(REConstants.REGEX_USERNAME, loginDto.getUsername())) {
            throw new GlobalException(ResultCodeEnum.USERNAME_FORMAT_ERROR);
        }
        SysUserInfo sysUserInfo = sysUserInfoMapper.selectByUsername(loginDto.getUsername());
        log.info("用户登录：sysUserInfo:{}", sysUserInfo);
        if (sysUserInfo == null) {
            throw new GlobalException(ResultCodeEnum.LOGIN_ERROR);
        }
        if (sysUserInfo.getIsDeleted().equals(UserEnums.DELETE.value())) {
            throw new GlobalException(ResultCodeEnum.USER_DELETE);
        }
        if (sysUserInfo.getUserStatus().equals(UserEnums.DISABLE.value())) {
            throw new GlobalException(ResultCodeEnum.USER_DISABLE);
        }
        if (!sysUserInfo.getPassword().equals(loginDto.getPassword())) {
            throw new GlobalException(ResultCodeEnum.PASSWORD_ERROR);
        }
        sysUserInfo.setPassword(null);
        //生成token
        HashMap<String, Object> map = new HashMap<>();
        map.put(TokenConstants.USER_ID, sysUserInfo.getId());
        map.put(TokenConstants.USER_NAME, sysUserInfo.getUsername());
        String token = TokenConstants.TOKEN_PREFIX + JWT.create()
                .setSigner(TokenConstants.SIGNER)
                .setPayload(TokenConstants.SYS_USER, map)
                .sign();
        //将token放入到redis
        redisTemplate.opsForValue().set(RedisConstants.SYS_USER_LOGIN_KEY_TOKEN + token,
                JSON.toJSONString(sysUserInfo),
                TokenConstants.TOKEN_EXPIRATION_TIME,
                TimeUnit.SECONDS);

        return token;
    }
    //获取用户权限列表
    @Override
    public List<String> findUserPermsList(Long userId) {

            //是则忽略租户拦截
            InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());
            List<RoleResVo> userPermsList = sysRoleMapper.findUserPermsList(userId);
            log.info("用户权限列表：userPermsList:{}", userPermsList);
            List<RoleResVo> deduplicatedList = deduplicate(userPermsList);
            log.info("去重后的用户权限列表：deduplicatedList:{}", deduplicatedList);
            List<String> list = deduplicatedList.stream().map(RoleResVo::getPermission).collect(Collectors.toList());
            log.info("用户权限列表getPermission：list:{}", list);
            return list;




    }

    @Override
    public SysUserInfo getCurrentUser(String token) {
        log.info("获取当前用户：token:{}", token);
        String user = (String) redisTemplate.opsForValue().get(RedisConstants.SYS_USER_LOGIN_KEY_TOKEN + token);
        if (!StringUtils.hasText(user)) {
            throw new GlobalException(ResultCodeEnum.LOGIN_AUTH);
        }
        try {
            return JSONUtils.toBean(user, SysUserInfo.class);
        }catch (JsonProcessingException e) {
            throw new GlobalException(ResultCodeEnum.LOGIN_AUTH);
        }

    }
    //获取当前登录用户的菜单树
    @Override
    public List<SysResourceVo> getSysResourceList(Long id) {
//        List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, id));
//        List<Long> roleIds = sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        List<SysResourceVo>  list = deduplicateSysResource(sysResourceMapper.SelectResourceList(id));
        return list;
    }

    /**
     * @description: list集合去重
     * @author: cjm
     * @date: 2024/9/20 17:20
     * @param:
     * @return:
     **/
    public  List<RoleResVo> deduplicate(List<RoleResVo> list) {
        return list.stream()
                .distinct()
                .filter(item -> item != null && item.getPermission() != null)
                .collect(Collectors.toList());
    }
    /**
     * @description: 对得到的菜单进行去重
     * @author: cjm
     * @date: 2024/11/20 11:26
     * @param: [list]
     * @return: java.util.List<com.cjm.one.model.system.entity.SysResource>
     **/
    public  List<SysResourceVo> deduplicateSysResource(List<SysResourceVo> list) {
        return list.stream()
                .distinct()
                .filter(item -> item != null && item.getRoutePath() != null)
                .collect(Collectors.toList());
    }



}
